package com.lagou.edu.factory;

import com.lagou.edu.annotation.Autowired;
import com.lagou.edu.annotation.Service;
import com.lagou.edu.service.PackageScanner;
import com.lagou.edu.service.impl.ClasspathPackageScanner;
import com.lagou.edu.utils.StringUtil;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 应癫
 * <p>
 * 工厂类，生产对象（使用反射技术）
 */
public class BeanFactory {

    /**
     * 任务一：读取解析xml，通过反射技术实例化对象并且存储待用（map集合）
     * 任务二：对外提供获取实例对象的接口（根据id获取）
     */

    private static Map<String, Object> map = new HashMap<>();  // 存储对象


    static {

        // 1、扫描beans，通过反射技术实例化对象并且存储待用（map集合）
        scans();

        // 2、初始化bean属性
        map.keySet().forEach(beanName -> {
            Object o = map.get(beanName);
            Field[] fields = o.getClass().getDeclaredFields();
            Arrays.stream(fields).forEach(filed -> {
                Autowired autowired = filed.getAnnotation(Autowired.class);
                // 非autowired 暂不处理
                if (autowired == null) {
                    return;
                }

                String filedName = filed.getName();
                Object filedValue = map.get(filedName);
                // 给变量赋值
                try {
                    filed.setAccessible(true);
                    filed.set(o, filedValue);
                } catch (Exception e) {
                    e.printStackTrace();
                }

            });


        });

    }

    private static void scans() {
        PackageScanner scanner = new ClasspathPackageScanner("com.lagou.edu");
        try {
            List<String> fullyQualifiedClassNameList = scanner.getFullyQualifiedClassNameList();
            for (String path : fullyQualifiedClassNameList) {
                try {
                    Class<?> aClass = Class.forName(path);
                    Service service = aClass.getAnnotation(Service.class);
                    // 非service 暂不处理
                    if (service == null) {
                        continue;
                    }
                    // 实例化之后的对象
                    Object o = aClass.newInstance();
                    String beanName = service.value();
                    if (beanName == null || beanName.isEmpty()) {
                        beanName = aClass.getSimpleName();
                    }
                    String id = StringUtil.toLowerCaseFirstOne(beanName);
                    // 存储到map中待用
                    map.put(id, o);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    // 任务二：对外提供获取实例对象的接口（根据id获取）
    public static Object getBean(String id) {
        return map.get(id);
    }

    public static void main(String[] args) {
        Object transferService = BeanFactory.getBean("proxyFactory");;
        System.out.println(transferService);

    }

}
